<script setup lang="ts">
import { h, ref, computed, watch } from "vue"
import CollapsibleForm from "../collapsible-form/CollapsibleForm.vue"
import FilterSettings from "../filter-settings/FilterSettings.vue"
import { defaultRenderers } from "./renderers"
import type { Filter, Renderer } from "./types"
import { useProvideAppendFormItem } from "./context"

const ifAppend = ref(true)
useProvideAppendFormItem(ifAppend)

import "../collapsible-form/style.css"

export type Props<T = any> = {
  uniqueKey?: string
  filters: Filter<T>[]
  renderers?: Renderer[]
}

const model = defineModel<any>({ default: {} })

const props = withDefaults(defineProps<Props>(), {
  uniqueKey: "prop",
  renderers: () => defaultRenderers,
})

watch(
  () => props.filters,
  () => {
    if (props.filters && props.filters.length > 0) {
      for (const filter of props.filters) {
        if (!Object.keys(model.value).includes(filter.prop)) {
          model.value[filter.prop] = null
        }
      }
    }
  },
  { immediate: true },
)

function findRendererComponent(filter: Filter) {
  const renderer = props.renderers.find((item) => item.supports(filter))
  if (renderer) {
    return renderer.component
  }
  return () => h("div", "没有匹配的组件")
}

const selectedFilters = ref<Filter[]>([])

const computedFilter = computed(() => {
  return (
    selectedFilters.value
      // 过滤掉隐藏的查询条件
      .filter((item) => !item.hidden)
      .map((item) => {
        return { ...item, component: findRendererComponent(item) }
      })
  )
})

const openFilterSettings =() => {
  ifAppend.value = false
  useProvideAppendFormItem(ifAppend)
}
</script>

<template>
  <CollapsibleForm>
    <template #filters>
      <template v-for="filter in computedFilter" :key="filter[props.uniqueKey]">
        <template v-if="filter.type !== 'custom'">
          <component
            :is="filter.component"
            v-bind="{
              filter,
              params: model,
              filters: props.filters,
              value: model[filter.prop],
              onChange(value: any) {
                model[filter.prop] = value
              },
            }"
          />
        </template>
        <template v-else>
          <slot
            :name="`filters-${filter[props.uniqueKey]}`"
            v-bind="{
              filter: filter,
              params: model,
              filters: props.filters,
              value: model[filter.prop],
              onChange(value: any) {
                model[filter.prop] = value
              },
            }"
          ></slot>
        </template>
      </template>
    </template>
    <template #actions>
      <slot name="default"> </slot>
      <FilterSettings @openFilterSettings="openFilterSettings" v-model="selectedFilters" :filters="props.filters" />
    </template>
  </CollapsibleForm>
</template>
